package com.limingru.newbee.service.impl;

import com.limingru.newbee.api.vo.CategoryFirstLevelVO;
import com.limingru.newbee.api.vo.CategorySecondLevelVO;
import com.limingru.newbee.api.vo.CategoryThirdLevelVO;
import com.limingru.newbee.common.CategoryEnum;
import com.limingru.newbee.dao.CategoryMapper;
import com.limingru.newbee.entity.Category;
import com.limingru.newbee.service.CategoryService;
import com.limingru.newbee.util.BeanUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl implements CategoryService {
    @Autowired
    CategoryMapper categoryMapper;

    @Override
    public List<CategoryFirstLevelVO> getCategories() {
        ArrayList<CategoryFirstLevelVO> categoryFirstLevelVOS = new ArrayList<>();
        List<Category> firstLevelCateroies = categoryMapper.selectCategoriesByParentIdsAndLevel(Collections.singletonList(0L), CategoryEnum.CATEGORY_FIRST_LEVEL.getCategoryLevel());
        if (!CollectionUtils.isEmpty(firstLevelCateroies)) {
            List<Long> firstLevelCategoryIds = firstLevelCateroies.stream().map(Category::getCategoryId).collect(Collectors.toList());
            List<Category> secondLevelCategories = categoryMapper.selectCategoriesByParentIdsAndLevel(firstLevelCategoryIds, CategoryEnum.CATEGORY_SECOND_LEVEL.getCategoryLevel());
            if (!CollectionUtils.isEmpty(secondLevelCategories)) {
                List<Long> secondLevelCategoryIds = secondLevelCategories.stream().map(Category::getCategoryId).collect(Collectors.toList());
                List<Category> thirdLevelCategories = categoryMapper.selectCategoriesByParentIdsAndLevel(secondLevelCategoryIds, CategoryEnum.CATEGORY_THIRD_LEVEL.getCategoryLevel());
                if (!CollectionUtils.isEmpty(thirdLevelCategories)) {
                    Map<Long, List<Category>> thirdCategoryGroupMap = thirdLevelCategories.stream().collect(Collectors.groupingBy(Category::getParentId));
                    List<CategorySecondLevelVO> secondLevelVOList = new ArrayList<>();
                    for (Category c : secondLevelCategories) {
                        List<CategoryThirdLevelVO> categoryThirdLevelVOS = new ArrayList<>();
                        CategorySecondLevelVO categorySecondLevelVO = new CategorySecondLevelVO();
                        BeanUtils.copyProperties(c, categorySecondLevelVO);
                        Long key = c.getCategoryId();
                        if (thirdCategoryGroupMap.containsKey(key)) {
                            categoryThirdLevelVOS = BeanUtil.copyList(thirdCategoryGroupMap.get(key), CategoryThirdLevelVO.class);
                        }
                        categorySecondLevelVO.setCategoryThirdLevelVOList(categoryThirdLevelVOS);
                        secondLevelVOList.add(categorySecondLevelVO);
                    }

                    if (!CollectionUtils.isEmpty(secondLevelVOList)) {
                        Map<Long, List<CategorySecondLevelVO>> secondLevelGroupMap = secondLevelVOList.stream().collect(Collectors.groupingBy(CategorySecondLevelVO::getParentId));
                        List<CategoryFirstLevelVO> categoryFirstLevelVOList = new ArrayList<>();
                        for (Category c : firstLevelCateroies) {
                            CategoryFirstLevelVO categoryFirstLevelVO = new CategoryFirstLevelVO();
                            BeanUtils.copyProperties(c, categoryFirstLevelVO);
                            List<CategorySecondLevelVO> categorySecondLevelVOS = new ArrayList<>();
                            Long key = c.getCategoryId();
                            if (secondLevelGroupMap.containsKey(key)) {
                                categorySecondLevelVOS = BeanUtil.copyList(secondLevelGroupMap.get(key), CategorySecondLevelVO.class);
                            }
                            categoryFirstLevelVO.setCategorySecondLevelVOList(categorySecondLevelVOS);
                            categoryFirstLevelVOList.add(categoryFirstLevelVO);
                        }
                        return categoryFirstLevelVOList;
                    }
                }
            }
            return categoryFirstLevelVOS;
        }
        return null;
    }
}
